/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ru.ssau.datamanager;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import ru.ssau.entities.DataAccessException;
import ru.ssau.entities.Message;
import ru.ssau.entities.AuthorizationInfo;
import ru.ssau.entities.Thread;
import ru.ssau.entities.User;
import ru.ssau.utils.DatabaseUtil;


@Stateless(name="DataManager", mappedName="ejb/DataManager")
public class DataManagerBean implements DataManager {

    public static final String VALUES_XML_TAG = "values";

    @PersistenceContext
    EntityManager entityManager;


    /*Thread section*/
    public void addThread(String caption) throws DataAccessException {
        Thread thread = new Thread(caption);
        entityManager.persist(thread);
    }

    public void addThread(Thread thread) throws DataAccessException {
        entityManager.persist(thread);
    }

    public void replaceThread(Integer id, String caption) throws DataAccessException {
        Thread thread = entityManager.find(ru.ssau.entities.Thread.class, id);
        if(thread != null) {
            thread.setCaption(caption);
        }
    }

    public void replaceThread(Thread thread) throws DataAccessException {
        entityManager.merge(thread);
    }

    public Thread getThreadById(Integer id) throws DataAccessException {
        Thread thread = entityManager.find(ru.ssau.entities.Thread.class, id);
        return thread;
    }

    public void deleteThreadById(Integer id) throws DataAccessException {
        Thread thread = entityManager.find(ru.ssau.entities.Thread.class, id);
        if(thread != null) {
            entityManager.remove(thread);
        }
    }

    public Collection<Thread> getAllThreads() throws DataAccessException {
        List<Thread> threads = entityManager.createNamedQuery(Thread.FIND_ALL_THREADS, Thread.class).getResultList();
        return threads;
    }

    public Collection<Thread> findThreadsByCaption(String caption) throws DataAccessException {
        List<Thread> threads = entityManager.createNamedQuery(Thread.FIND_THREADS_BY_CAPTION, Thread.class).
                setParameter(1, DatabaseUtil.getContainsPattern(caption.toUpperCase())).getResultList();
        return threads;
    }

    /*Message section*/
    public void addMessage(String caption, String text, Integer userId, Integer threadId, Date postDate) throws DataAccessException {
        Thread thread = entityManager.find(Thread.class, threadId);
        User user = entityManager.find(User.class, userId);
        Message message = new Message(caption, text, postDate, user, thread);
        thread.getMessages().add(message);
        entityManager.persist(message);
    }

    public void addMessage(Message message, Integer userId, Integer threadId) throws DataAccessException {
        User user = entityManager.find(User.class, userId);
        message.setUser(user);

        Thread thread = entityManager.find(Thread.class, threadId);
        message.setThread(thread);
        thread.getMessages().add(message);

        entityManager.persist(message);
    }

    public void replaceMessage(Integer id, String caption, String text, Integer userId, Integer threadId, Date postDate) throws DataAccessException {
        Message message = entityManager.find(Message.class, id);
        if(message == null) return;
        Thread newThread = entityManager.find(Thread.class, threadId);
        User newUser = entityManager.find(User.class, userId);
        if(!message.getThread().getId().equals(threadId)) {
            Thread oldThread = message.getThread();
            oldThread.getMessages().remove(message);
            newThread.getMessages().add(message);
            message.setThread(newThread);
        }
        message.setUser(newUser);
        message.setCaption(caption);
        message.setText(text);
        message.setPostDate(postDate);
    }

    public void replaceMessage(Message message, Integer newUserId, Integer newThreadId) throws DataAccessException {
        if(!message.getUserId().equals(newUserId)) {
            User newUser = entityManager.find(User.class, newUserId);
            message.setUser(newUser);
        }
        
        if(!message.getId().equals(newThreadId)) {
            Thread oldThread = entityManager.merge(message.getThread());
            oldThread.getMessages().remove(message);

            Thread newThread = entityManager.find(Thread.class, newThreadId);
            newThread.getMessages().add(message);
            message.setThread(newThread);
        }

        message = entityManager.merge(message);
    }

    public Message getMessageById(Integer id) throws DataAccessException {
        Message message = entityManager.find(Message.class, id);
        entityManager.refresh(message);
        return message;
    }

    public void deleteMessageById(Integer id) throws DataAccessException {
        Message message = entityManager.find(Message.class, id);
        if(message != null) {
            Thread thread = message.getThread();
            thread.getMessages().remove(message);
            entityManager.remove(message);
        }
    }

    public Collection<Message> getAllMessages() throws DataAccessException {
        List<Message> messages = entityManager.createNamedQuery(Message.FIND_ALL_MESSAGES, Message.class).getResultList();
        return messages;
    }

    public Collection<Message> findMessagesByCaption(String caption) throws DataAccessException {
        List<Message> messages = entityManager.createNamedQuery(Message.FIND_MESSAGESS_BY_CAPTION, Message.class).
                setParameter(1, DatabaseUtil.getContainsPattern(caption.toUpperCase())).getResultList();
        return messages;
    }

    /*User section*/
    public void addUser(String name, Date regDate, String info, String login, String password) throws DataAccessException {
        AuthorizationInfo authInfo = new AuthorizationInfo(login, password);
        User user = new User(name, regDate, info, authInfo);
        authInfo.setUser(user);
        entityManager.persist(user);
    }

    public void addUser(User user) throws DataAccessException {
        AuthorizationInfo authInfo = user.getAuthorizationInfo();
        authInfo.setUser(user);
        entityManager.persist(user);
    }

    public void replaceUser(Integer id, String name, Date regDate, String info, String login, String password) throws DataAccessException {
        User user = entityManager.find(User.class, id);
        if(user != null) {
            user.setName(name);
            user.setInfo(info);
            user.setRegistrationDate(regDate);
            user.getAuthorizationInfo().setLogin(login);
            user.getAuthorizationInfo().setPassword(password);
        }
    }

    public void replaceUser(User user) throws DataAccessException {
        entityManager.merge(user);
    }

    public User getUserById(Integer id) throws DataAccessException {
        User user = entityManager.find(User.class, id);
        return user;
    }

    public void deleteUserById(Integer id) throws DataAccessException {
        User user = entityManager.find(User.class, id);
        if(user != null) {
            entityManager.remove(user);
        }
    }

    public Collection<User> getAllUsers() throws DataAccessException {
        List<User> users = entityManager.createNamedQuery(User.FIND_ALL_USERS, User.class).getResultList();
        return users;
    }

    public Collection<User> findUsersByName(String name) throws DataAccessException {
        List<User> users = entityManager.createNamedQuery(User.FIND_USERS_BY_NAME, User.class).
                setParameter(1, DatabaseUtil.getContainsPattern(name.toUpperCase())).getResultList();
        return users;
    }

}
